import com.mosesSupposes.fuse.PennerEasing;

import gugga.collections.HashTable;
import gugga.utils.DebugUtils;

/**
 * @author Todor Kolev
 */
class gugga.tween.AbstractTween 
{
	private var mInitialValues : HashTable;
	
	private var mSubject : Object;
	public function get Subject() : Object
	{
		return mSubject;
	}
	
	public var mTweeningProperties : HashTable;
	public function get TweeningProperties() : HashTable
	{
		return mTweeningProperties;
	}
	
	public var Duration : Number = 10;
	
	/**
	* Generates elastic easing in tween where equation for motion is based on Hooke's Law of <code>F = -kd</code>.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param a		(optional) amplitude, or magnitude of wave's oscillation
	* @param p		(optional) period
	* @return		final position
	*/
	public var EasingEquation : Function = PennerEasing.linear;
	
	public var TweenFinishedDelegate : Function;
	public var TweenUpdateDelegate : Function;
	
	public var Option1 : Number;
	public var Option2 : Number;
	
	private var mDurationElapsed : Number = 0;
	public function get DurationElapsed() : Number
	{
		return mDurationElapsed;
	}
	
	public function get Finished() : Boolean
	{
		return (mDurationElapsed >= Duration);
	}
	
	public function AbstractTween(aSubject:Object, aTweeningProperties:HashTable) 
	{
		super();
		
		mSubject = aSubject;
		
		mTweeningProperties = new HashTable();
		mInitialValues = new HashTable();
		
		for (var key:String in aTweeningProperties)
		{
			mInitialValues[key] = aSubject[key];
			mTweeningProperties[key] = aTweeningProperties[key];
		}
	}
	
	public function update() : Void
	{
		increaseDurationElapsed();
		
		for (var key:String in mTweeningProperties)
		{
			mSubject[key] = EasingEquation(
				mDurationElapsed,
				mInitialValues[key],
				mTweeningProperties[key] - mInitialValues[key],
				Duration,
				Option1,
				Option2
			);
		}
		
		TweenUpdateDelegate();
		
		if(Finished)
		{
			TweenFinishedDelegate();
		}
	}	
	
	private function increaseDurationElapsed() : Void 
	{
		throw new Error("Not implemented");
	}
}